﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Netfraction.Network.Protocol.BASE.Factory
{
    public class FactoryINF : ProtocolMessageFactory
    {
        public enum ParameterEnum : int
        {
            SessionID = 1,
            ClientID = 2,
            PrivateID = 3,
            IPv4_Address = 4,
            IPv6_Address = 5,
            UDPv4_Port = 6,
            UDPv6_Port = 7,
            ShareSize = 8,
            SharedFilesCount = 9,
            ClientVersionIdentifier = 10,
            MaximumUploadSpeed = 11,
            MaximumDownloadSpeed = 12,
            MaximumUploadSlots = 13,
            AutomaticSlotAllocatorSpeedLimit = 14,
            MinimumUploadConnectionsForAutoSlotAlloc = 15,
            EmailAddress = 16,
            NickOrHubName = 17,
            Description = 18,
            UserNormalCount = 19,
            UserRegisteredCount = 20,
            UserOperatorCount = 21,
            Token = 22,
            ClientType = 23,
            AwayStatus = 24,
            SupportedFeatures = 25,
            RefererURL = 26
        }

        public FactoryINF() : base()
        {
            mParameterCodes = new List<string>(new string[]
            {"ID", "PD", "I4", "I6", "U4", "U6", "SS", "SF", "VE", "US", "DS", "SL", "AS", 
                "AM", "EM", "NI", "DE", "HN", "HR", "HO", "TO", "CT", "AW", "SU", "RF"});
        }

        public override ProtocolMessage Create(ProtocolMessage.MessageTypeEnum messageType, Dictionary<int, object> parameters)
        {
            ProtocolMessage proto = null;
            switch (messageType)
            {
                case ProtocolMessage.MessageTypeEnum.Broadcast:
                    if (!parameters.ContainsKey((int)ParameterEnum.SessionID) || parameters[(int)ParameterEnum.SessionID] == null)
                        return null; // check that calling code handles this null result

                    proto = new ProtocolMessage(messageType, ProtocolFeatureBASE.FeatureActions.ActionINF, parameters[(int)ParameterEnum.SessionID] as string);
                    break;
                case ProtocolMessage.MessageTypeEnum.Client:
                    proto = new ProtocolMessage(messageType, ProtocolFeatureBASE.FeatureActions.ActionINF);
                    break;
                case ProtocolMessage.MessageTypeEnum.Direct:
                    break;
                case ProtocolMessage.MessageTypeEnum.Echo:
                    break;
                case ProtocolMessage.MessageTypeEnum.Feature:
                    break;
                case ProtocolMessage.MessageTypeEnum.Hub:
                    break;
                case ProtocolMessage.MessageTypeEnum.Info:
                    break;
                case ProtocolMessage.MessageTypeEnum.Udp:
                    break;
                default:
                    break;
            }
            if (proto != null)
            {
                foreach (ParameterEnum e in parameters.Keys)
                {
                    proto.Parameters.Add(new ProtocolParameter(GetParameterCodeForParameter((ParameterEnum)e), parameters[(int)e].ToString()));
                }
                proto.Parameters.Add(new ProtocolParameter("SU", "TCP4"));
            }
            return proto;
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification="Method is simple, but with many required case statements.")]
        private static string GetParameterCodeForParameter(ParameterEnum param)
        {
            switch (param)
            {
                case ParameterEnum.SessionID:
                    return "SessionId";
                case ParameterEnum.ClientID:
                    return "ID";
                case ParameterEnum.PrivateID:
                    return "PD";
                case ParameterEnum.IPv4_Address:
                    return "I4";
                case ParameterEnum.IPv6_Address:
                    return "I6";
                case ParameterEnum.UDPv4_Port:
                    return "U4";
                case ParameterEnum.UDPv6_Port:
                    return "U6";
                case ParameterEnum.ShareSize:
                    return "SS";
                case ParameterEnum.SharedFilesCount:
                    return "SF";
                case ParameterEnum.ClientVersionIdentifier:
                    return "VE";
                case ParameterEnum.MaximumUploadSpeed:
                    return "US";
                case ParameterEnum.MaximumDownloadSpeed:
                    return "DS";
                case ParameterEnum.MaximumUploadSlots:
                    return "SL";
                case ParameterEnum.AutomaticSlotAllocatorSpeedLimit:
                    return "AS";
                case ParameterEnum.MinimumUploadConnectionsForAutoSlotAlloc:
                    return "AM";
                case ParameterEnum.EmailAddress:
                    return "EM";
                case ParameterEnum.NickOrHubName:
                    return "NI";
                case ParameterEnum.Description:
                    return "DE";
                case ParameterEnum.UserNormalCount:
                    return "HN";
                case ParameterEnum.UserRegisteredCount:
                    return "HR";
                case ParameterEnum.UserOperatorCount:
                    return "HO";
                case ParameterEnum.Token:
                    return "TO";
                case ParameterEnum.ClientType:
                    return "CT";
                case ParameterEnum.AwayStatus:
                    return "AW";
                case ParameterEnum.SupportedFeatures:
                    return "SU";
                case ParameterEnum.RefererURL:
                    return "RF";
                default:
                    return "";
            }
        }
    }
}
